package com.cictec.middleware.gps.caculate;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.alibaba.fastjson.JSON;
import com.cictec.middleware.commons.utils.PMSUtils;
import com.cictec.middleware.commons.utils.log.MultiLog;
import com.cictec.middleware.core.entity.Bus;
import com.cictec.middleware.core.entity.BusTimingPointSupply;
import com.cictec.middleware.core.entity.Device;
import com.cictec.middleware.gps.caculate.service.BusMileageService;
import com.cictec.middleware.gps.engine.BusInstance;
import com.cictec.middleware.gps.engine.TimingPoint;
import com.cictec.middleware.gps.engine.caculate.entity.BusMileageData;
import com.cictec.middleware.gps.engine.service.DataStorageToRedisService;
import com.cictec.middleware.gps.engine.utils.MultiLogUtil;
import com.cictec.middleware.gps.service.BusService;
import com.cictec.middleware.gps.service.BusTimingPointService;
import com.cictec.middleware.gps.service.DeviceService;

@Repository
public class BusMileageEngine {

	public static Logger logger = LoggerFactory.getLogger(BusMileageEngine.class);

	@Autowired
	private BusMileageService busMileageService;
	@Autowired
	private BusService busService;
	@Autowired
	private DeviceService deviceService;
	@Autowired
	protected DataStorageToRedisService dataStorageToRedisService;
	@Autowired
	protected BusTimingPointService busTimingPointService;
	
	/**
	 * 根据 日期， 线路， 车牌号 计算车辆当天的 里程
	 * 
	 * @param date
	 * @param linename
	 * @param plate
	 */
	public void executeMileage(BusMileageData entity) throws Exception {

		/*
		 * 1、数据回放前-数据清洗 2、数据回放前-业务信息重置 3、数据回放 4、里程计算、趟次计算 5、数据存储 6、清理缓存信息
		 */

		// 1、数据回放前-数据清洗 【针对多线路切换，剔除无效的切换信息】【对位置点进行修复（没实现）--没有上下行信息等的修复】
		busMileageService.beautifyOrgPositions(entity);

		// 2、数据回放前-业务信息重置
		busMileageService.refrashBaseInfo(entity);

		// 3、数据回放
		busMileageService.playback(entity);

		// 4、里程计算、趟次计算
		busMileageService.caculateSegment(entity);

		// 5、数据存储
		busMileageService.saveBusMileageCaculate(entity);
		
		// 6、清理缓存信息
		busMileageService.clearBusMileageCaculate(entity);
	}

	/**
	 * 获取里程计算初始化参数信息
	 * @param supply
	 * @return
	 * @throws Exception
	 */
	public BusMileageData getInitBusMileageData(BusTimingPointSupply supply) throws Exception {

		String dataFrom = supply.getDataFrom();
		String devCode = supply.getSupDevCode();
		String date = supply.getSupDate();
		Bus bus = busService.selectBusByDevCode(devCode);
		if(bus == null){
			logger.debug("{} 查询车辆信息 {}", devCode, JSON.toJSONString(bus));
			throw new Exception(devCode + " 根据设备号查询车辆信息不存在：结束");
		}
		Device device = deviceService.selectDeviceByBusUuid(bus.getBusUuid());
		
		MultiLog log = MultiLogUtil.getBusMileageLog(date, devCode, bus.getBusPlateNumber());
		
		try {
			BusMileageData calculate = new BusMileageData();
			
			log.debug("{}-{}：开始计算", devCode, bus.getBusPlateNumber());
			logger.debug("{}-{}：开始计算", devCode, bus.getBusPlateNumber());
			log.debug("{}-{}：获取原始位置信息", devCode, bus.getBusPlateNumber());
			logger.debug("{}-{}：获取原始位置信息", devCode, bus.getBusPlateNumber());
			List<TimingPoint> positionList = null;
			
			if(dataFrom.equals("db")){
				positionList = busTimingPointService.readData(date, devCode);
				log.debug("{}-{}：读取车辆原始位置信息 总计 {} 条位置信息", devCode, bus.getBusPlateNumber(), positionList.size());
				logger.debug("{}-{}：读取车辆原始位置信息 总计 {} 条位置信息", devCode, bus.getBusPlateNumber(), positionList.size());
				
			}else if(dataFrom.equals("redis")){
				positionList = dataStorageToRedisService.getPositionTMFromRedis(date, devCode, true);
			}
			

			if(positionList.size() > 0){
				
				// 过滤错误数据 start
				List<TimingPoint> newList = new ArrayList<TimingPoint>();
				for (TimingPoint timingPoint : positionList) {
					if (timingPoint.getLatitude().equals("34.00049408162633")
							&& timingPoint.getLongitude().equals("108.22765773764283")) {
						logger.error("过滤错误位置信息:{} --->{}", devCode, JSON.toJSONString(timingPoint));
					} else {
						newList.add(timingPoint);
					}
				}
				positionList = newList;
				// 过滤错误数据 end
				
				
				calculate.date = supply.getSupDate();
				calculate.busUuid = bus.getBusUuid();
				calculate.plate = bus.getBusPlateNumber();
				calculate.orgTimingPoints = positionList;
				calculate.busInstance = new BusInstance(bus, device);
				calculate.devCode = devCode;
				
				return calculate;
			}else{
				log.debug("{}-{}：没有位置信息,结束里程计算", devCode, bus.getBusPlateNumber());
				logger.debug("{}-{}：没有位置信息,结束里程计算", devCode, bus.getBusPlateNumber());
				throw new Exception(devCode + " 根据设备号查询车辆信息不存在：结束");
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			String msg = PMSUtils.format("{}-{}：错误！！！！！！！！！！！！！！！", devCode, bus.getBusPlateNumber(), e);
			log.debug(msg);
			logger.debug(msg);
			throw new Exception(devCode + " 根据设备号查询车辆信息不存在：结束");
		}
	}
}
